from . import models, getweb
import re, numpy as np
from django.core.exceptions import ObjectDoesNotExist
import itertools  # 排列组合工具
from django.db.models import Q, Max


# 更新所有投注的中奖信息
def check_all_bonus():
    """
    :return:更新后退出，无返回数据
    """
    # recent_history_phase = models.phase_data.objects.aggregate(Max('phasenum'))
    # if recent_history_phase['phasenum__max'] is None:  # __max是aggregate函数自动添加的后缀，注意是两个下划线。如果用count则是date__count
    #     return
    # else:
    #     maxphase = recent_history_phase['phasenum__max']

    checking = models.bet_data.objects.filter(ischeck=False)

    for che in checking:
        if not (che.ischeck):
            try:
                phaseinfo = models.phase_data.objects.get(phasenum=che.phasenum)  # get如查询不到，会抛出doesnoexist异常
                firstprice = phaseinfo.firstprice
                secondprice = phaseinfo.secondprice
            except ObjectDoesNotExist:
                continue  # 说明查询不到该期开奖信息，跳出该次循环，进入下一个循环
            bonuslevel = check_one_note(che)
            models.bet_data.objects.filter(id=che.id).update(bonuslevel=bonuslevel)
            models.bet_data.objects.filter(id=che.id).update(ischeck=True)
            models.bet_data.objects.filter(id=che.id).update(
                bonusprice=calculate_bonus(bonuslevel, che.multiple, che.additonal_bet, firstprice, secondprice))


# 根据期数匹配中奖信息
def check_bonus(phase_num):
    """
    该函数不用了
    :param phase_num: 投注期号，如为空“all”，则查询所有未被检测是否中的投注信息，并不返回数据
    :return: 检查是否中奖后，返回符合该期号的所有投注数据
    """
    try:
        checking = models.bet_data.objects.filter(phasenum=phase_num)  # get如查询不到，会抛出doesnoexist异常
    except ObjectDoesNotExist:
        return None

    for che in checking:
        if not (che.ischeck):
            models.bet_data.objects.filter(id=che.id).update(bonuslevel=check_one_note(che))
            models.bet_data.objects.filter(id=che.id).update(ischeck=True)
    checking = models.bet_data.objects.filter(phasenum=phase_num)
    return checking


# 计算奖金
def calculate_bonus(bonuslevel, multiple, additonal_bet, firstprice, secondprice):
    """

        :param bonuslevel: 奖励等级
        :param multiple: 倍数
        :param additonal_bet: 追加，双色球无追加，默认为false
        :param firstprice: 该期彩票的一等奖金额
        :param secondprice: 该期彩票的二等奖金额
        :return: 该注彩票的中奖金额，int类型
        """
    total_bonus = 0

    if bonuslevel == '未中奖': return total_bonus
    if bonuslevel == '一等奖':
        single_bonus = re.sub("\D", "", firstprice)  # 将，去除，转换成纯数字
        if single_bonus == '': single_bonus = 0
        if additonal_bet: multiple = multiple * 1.8
        total_bonus = total_bonus + int(int(single_bonus) * multiple)
    if bonuslevel == '二等奖':
        single_bonus = re.sub("\D", "", secondprice)
        if single_bonus == '': single_bonus = 0
        if additonal_bet: multiple = multiple * 1.8
        total_bonus = total_bonus + int(int(single_bonus) * multiple)

    if not ((bonuslevel == '一等奖') or (bonuslevel == '二等奖')):
        tmp = bonuslevel

        try:
            single_bonus = models.reward_conditions.objects.filter(bonuslevel=tmp)  # get如查询不到，会抛出doesnoexist异常
        except ObjectDoesNotExist:
            single_bonus = 0  # 找不到默认为0
        single_bonus = single_bonus[0].single_bonus
        total_bonus = total_bonus + int(int(single_bonus) * multiple)

    return total_bonus


# 检测某注是否中奖
def check_one_note(one_note):
    redcheck = 0
    bluecheck = 0

    try:
        kailist = models.phase_data.objects.filter(phasenum=one_note.phasenum)  # get如查询不到，会抛出doesnoexist异常
    except ObjectDoesNotExist:
        return '未中奖'
    for kaijiang in kailist:
        redlist = []
        redlist.append(kaijiang.red1)
        redlist.append(kaijiang.red2)
        redlist.append(kaijiang.red3)
        redlist.append(kaijiang.red4)
        redlist.append(kaijiang.red5)
        redlist.append(kaijiang.red6)

        if (one_note.red1 in redlist):  redcheck += 1
        if (one_note.red2 in redlist):  redcheck += 1
        if one_note.red3 in redlist:  redcheck += 1
        if one_note.red4 in redlist:  redcheck += 1
        if one_note.red5 in redlist:  redcheck += 1
        if one_note.red6 in redlist: redcheck += 1
        if one_note.blue == kaijiang.blue: bluecheck += 1

        try:
            checktmp = models.reward_conditions.objects.get(red=redcheck, blue=bluecheck)  # get如查询不到，会抛出doesnoexist异常
            return checktmp.bonuslevel
        except ObjectDoesNotExist:
            break

    return '未中奖'  # 默认返回0


# 根据输入的redlist和bluelist生成投注组合数组，适合单注投注和胆拖
def combinations_notes(redlist, bluelist):
    notelist = []
    for red in itertools.combinations(redlist, 6):  # 从投注的红球中选5个
        for blue in itertools.combinations(bluelist, 1):
            note = red + blue
            notelist.append(note)
    return notelist


# 胆拖组合
def dantuo_combinations_notes(dan_red, tuo_red, bluelist):
    notelist = []
    for red in itertools.combinations(tuo_red, 6 - len(dan_red)):
        for blue in itertools.combinations(bluelist, 1):
            # 先排序，再返回
            redsort = tuple(dan_red) + tuple(red)
            redsort = list(redsort)
            redsort.sort()
            redsort = tuple(redsort)
            bluesort = list(blue)
            bluesort.sort()
            bluesort = tuple(bluesort)
            tem = redsort + bluesort  # TODO：元组元素个数为1时，会自动在后面添加一个，空元素，以区别于其他数据，这个要注意
            notelist.append(tem)
    return notelist


# 将投注信息写入数据库，都可以调用该函数写入
def save_notedata_to_DB(phasenum, notelist, multiple=1, add_bet=False):
    if not (notelist == []):
        note_list_db = []
        for note in notelist:
            tmp_bet_data = models.bet_data()
            tmp_bet_data.phasenum = phasenum
            tmp_bet_data.red1 = note[0]
            tmp_bet_data.red2 = note[1]
            tmp_bet_data.red3 = note[2]
            tmp_bet_data.red4 = note[3]
            tmp_bet_data.red5 = note[4]
            tmp_bet_data.red6 = note[5]
            tmp_bet_data.blue = note[6]
            tmp_bet_data.multiple = multiple
            note_list_db.append(tmp_bet_data)
        if not (note_list_db == []):
            models.bet_data.objects.bulk_create(note_list_db)  # 将投注信息写入数据库


# 查询最近一期中奖信息,并返回中奖信息
def query_recent_bonue_info():
    recent_phase = models.bet_data.objects.filter(~Q(bonuslevel='未中奖')).aggregate(Max('phasenum'))
    if recent_phase['phasenum__max'] is None:  # __max是aggregate函数自动添加的后缀，注意是两个下划线。如果用count则是date__count
        return ''
    else:
        maxphase = recent_phase['phasenum__max']

    record = models.bet_data.objects.filter(~Q(bonuslevel='未中奖'), phasenum=maxphase);
    b = np.zeros((6), dtype=np.int)  # 共有六级奖励，从0-5分别为一等奖至六等奖
    for r in record:
        if r.bonuslevel == '一等奖':
            b[0] = b[0] + 1
        if r.bonuslevel == '二等奖':
            b[1] = b[1] + 1
        if r.bonuslevel == '三等奖':
            b[2] = b[2] + 1
        if r.bonuslevel == '四等奖':
            b[3] = b[3] + 1
        if r.bonuslevel == '五等奖':
            b[4] = b[4] + 1
        if r.bonuslevel == '六等奖':
            b[5] = b[5] + 1

    returnstr = '恭喜' + maxphase + '期中：'
    for i in range(len(b)):
        if b[i] > 0:
            returnstr = returnstr + str(i + 1) + '等奖' + str(b[i]) + '注；'
    return returnstr


# 查询所有中奖投注
def query_win_bet_data():
    try:
        lottery = models.bet_data.objects.filter(~Q(bonuslevel='未中奖'), ~Q(bonuslevel='等待开奖'))
        total = lottery.count()
    except ObjectDoesNotExist:
        total = 0

    rows = []
    result = {"total": total, "rows": rows}
    if total == 0: return result
    for data in lottery:
        rows.append({'id': data.id, 'phasenum': data.phasenum, 'bonuslevel': data.bonuslevel, 'red1': data.red1,
                     'red2': data.red2, 'red3': data.red3, 'red4': data.red4, 'red5': data.red5, 'red6': data.red6,
                     'blue': data.blue, 'bonusprice': data.bonusprice, 'additonal_bet': data.additonal_bet,
                     'multiple': data.multiple}
                    )

    return result


# 查询所有待开奖投注
def query_wait_bet_data():
    try:
        lottery = models.bet_data.objects.filter(bonuslevel='等待开奖')
        total = lottery.count()
    except ObjectDoesNotExist:
        total = 0

    rows = []
    result = {"total": total, "rows": rows}
    if total == 0: return result
    for data in lottery:
        rows.append({'id': data.id, 'phasenum': data.phasenum, 'bonuslevel': data.bonuslevel, 'red1': data.red1,
                     'red2': data.red2, 'red3': data.red3, 'red4': data.red4, 'red5': data.red5, 'red6': data.red6,
                     'blue': data.blue, 'bonusprice': data.bonusprice, 'additonal_bet': data.additonal_bet,
                     'multiple': data.multiple}
                    )

    return result


# 查询所有未开奖投注
def btn_query_not_win_data():
    try:
        lottery = models.bet_data.objects.filter(bonuslevel='未中奖')
        total = lottery.count()
    except ObjectDoesNotExist:
        total = 0

    rows = []
    result = {"total": total, "rows": rows}
    if total == 0: return result
    for data in lottery:
        rows.append({'id': data.id, 'phasenum': data.phasenum, 'bonuslevel': data.bonuslevel, 'red1': data.red1,
                     'red2': data.red2, 'red3': data.red3, 'red4': data.red4, 'red5': data.red5, 'red6': data.red6,
                     'blue': data.blue, 'bonusprice': data.bonusprice, 'additonal_bet': data.additonal_bet,
                     'multiple': data.multiple}
                    )

    return result


# 获取开奖信息函数
def get_history_data(num=5):
    """
    :param num: 获取多少注投注，默认100
    :return:
    获取历史开奖信息，并返回
    需要将models转换成json特定格式，才能被bootstrap table插件读取。
    另一种为json对象格式，必须要有total和rows两个key，
    {"total": 2,"rows": [{"id": 0,"name": "Item 0","price": "$0"},{"id": 1,"name": "Item 1","price": "$1"}]}，
    且键的名字必须与下方columns的field值一样，才能读取到数据,但是如果后台
    没有处理的话，前台会在第一页显示全部数据，为client时，前台会提示：没有找到匹配的记录。
    """
    lottery = models.phase_data.objects.all().order_by("-date")[0:num]  # 获取最新100期数据
    total = lottery.count()
    rows = []
    result = {"total": total, "rows": rows}
    for data in lottery:
        rows.append({'phasenum': data.phasenum, 'date': data.date, 'red1': data.red1,
                     'red2': data.red2, 'red3': data.red3, 'red4': data.red4, 'red5': data.red5, 'red6': data.red6,
                     'blue': data.blue,
                     'firstnum': data.firstnum, 'firstprice': data.firstprice, 'secondnum': data.secondnum,
                     'secondprice': data.secondprice,
                     'totalbet': data.totalbet}
                    )

    return result


# 获取指定期号的开奖信息
def get_phasenum_history_data(phasenum):
    """
    :param phasenum: 指定期数
    :return:
    获取指定期数历史开奖信息，并返回
    需要将models转换成json特定格式，才能被bootstrap table插件读取。
    另一种为json对象格式，必须要有total和rows两个key，
    {"total": 2,"rows": [{"id": 0,"name": "Item 0","price": "$0"},{"id": 1,"name": "Item 1","price": "$1"}]}，
    且键的名字必须与下方columns的field值一样，才能读取到数据,但是如果后台
    没有处理的话，前台会在第一页显示全部数据，为client时，前台会提示：没有找到匹配的记录。
    """
    try:
        lottery = models.phase_data.objects.filter(phasenum=phasenum)
        total = lottery.count()
    except ObjectDoesNotExist:
        total = 0

    rows = []
    result = {"total": total, "rows": rows}
    for data in lottery:
        rows.append({'phasenum': data.phasenum, 'date': data.date, 'red1': data.red1,
                     'red2': data.red2, 'red3': data.red3, 'red4': data.red4, 'red5': data.red5, 'red6': data.red6,
                     'blue': data.blue,
                     'firstnum': data.firstnum, 'firstprice': data.firstprice, 'secondnum': data.secondnum,
                     'secondprice': data.secondprice,
                     'totalbet': data.totalbet}
                    )

    return result


# 获取投注信息函数
def get_bet_data(num=5):
    """
    :param num: 获取多少注投注，默认100
    :return: 返回投注信息
    """
    try:
        lottery = models.bet_data.objects.all().order_by("-phasenum")[0:num]  # 获取最新100期数据
        total = lottery.count()
    except ObjectDoesNotExist:
        total = 0

    rows = []
    result = {"total": total, "rows": rows}
    if total == 0: return result
    for data in lottery:
        rows.append({'id': data.id, 'phasenum': data.phasenum, 'bonuslevel': data.bonuslevel, 'red1': data.red1,
                     'red2': data.red2, 'red3': data.red3, 'red4': data.red4, 'red5': data.red5, 'red6': data.red6,
                     'blue': data.blue, 'bonusprice': data.bonusprice, 'additonal_bet': data.additonal_bet,
                     'multiple': data.multiple}
                    )

    return result


# 获取指定期号投注信息函数
def get_phasenum_bet_data(phasenum):
    """
    :param phasenum: 指定期号
    :return: 返回投注信息
    """
    try:
        lottery = models.bet_data.objects.filter(phasenum=phasenum)
        total = lottery.count()
    except ObjectDoesNotExist:
        total = 0

    rows = []
    result = {"total": total, "rows": rows}
    if total == 0: return result
    for data in lottery:
        rows.append({'id': data.id, 'phasenum': data.phasenum, 'bonuslevel': data.bonuslevel, 'red1': data.red1,
                     'red2': data.red2, 'red3': data.red3, 'red4': data.red4, 'red5': data.red5, 'red6': data.red6,
                     'blue': data.blue, 'bonusprice': data.bonusprice, 'additonal_bet': data.additonal_bet,
                     'multiple': data.multiple}
                    )

    return result


# 删除投注信息
def del_bet_data(phasenum_list):
    """

    :param phasenum_list: 如果为‘all’，则删除所有，如果不是all则删除phase列表中的期数信息
    :return:
    """
    if phasenum_list == 'all':
        models.bet_data.objects.all().delete()
        return "成功删除"

    for id in phasenum_list:
        ob = models.bet_data.objects.filter(id=id)
        ob.delete()


# 查询投注年份信息
def query_bet_yearlist():
    lottery = models.bet_data.objects.values("phasenum")  # 没有date字段，只能用phasenum了
    datelist = []
    for i in lottery:
        year = i['phasenum'][0:4]
        if not (year in datelist):
            datelist.append(year)  # 取年份
    return datelist


# 根据查询年份信息
def get_bet_by_year(year):
    if year == 'all':
        try:
            lottery = models.bet_data.objects.all()
            total = lottery.count()
        except ObjectDoesNotExist:
            total = 0
    else:

        try:
            lottery = models.bet_data.objects.all().filter(phasenum__startswith=year).order_by("-phasenum")
            total = lottery.count()
        except ObjectDoesNotExist:
            total = 0

    rows = []
    result = {"total": total, "rows": rows}
    if total == 0: return result
    for data in lottery:
        rows.append({'id': data.id, 'phasenum': data.phasenum, 'bonuslevel': data.bonuslevel, 'red1': data.red1,
                     'red2': data.red2, 'red3': data.red3, 'red4': data.red4, 'red5': data.red5, 'red6': data.red6,
                     'blue': data.blue, 'bonusprice': data.bonusprice, 'additonal_bet': data.additonal_bet,
                     'multiple': data.multiple}
                    )

    return result


# 查询历史开奖年份信息
def query_history_yearlist():
    lottery = models.phase_data.objects.values("date")
    datelist = []
    for i in lottery:
        year = i['date'][0:4]
        if not (year in datelist):
            datelist.append(year)  # 取年份
    return datelist


# 根据年份查询历史开奖信息
def get_history_by_year(year):
    try:
        lottery = models.bet_data.objects.all().filter(phasenum__startswith=year).order_by("-phasenum")
        total = lottery.count()
    except ObjectDoesNotExist:
        total = 0

    rows = []
    result = {"total": total, "rows": rows}
    if total == 0: return result
    for data in lottery:
        rows.append({'phasenum': data.phasenum, 'date': data.date, 'red1': data.red1,
                     'red2': data.red2, 'red3': data.red3, 'red4': data.red4, 'red5': data.red5, 'red6': data.red6,
                     'blue': data.blue,
                     'firstnum': data.firstnum, 'firstprice': data.firstprice, 'secondnum': data.secondnum,
                     'secondprice': data.secondprice,
                     'totalbet': data.totalbet}
                    )
    return result


#刷新开奖数据
def refresh_history_data():
    getweb.get_history_phasedata_from_360cp()
    return get_history_data()